﻿package com.tudou.js
{
    import com.tudou.log.*;
    import flash.events.*;
    import flash.external.*;
    import flash.utils.*;

    public class JSCall extends Object
    {
        private static var timer:Timer;
        private static var errorCount:uint = 0;
        private static var callMap:Array = [];
        public static var MAX_COUNT:uint = 600;
        private static var callbackMap:Array = [];
        private static const JS_CALL:Function = ExternalInterface.call;
        private static var avaible:int = -1;

        public function JSCall()
        {
            return;
        }// end function

        private static function dealCallback() : void
        {
            var _loc_1:Object = null;
            var _loc_2:int = 0;
            while (_loc_2 < callbackMap.length)
            {
                
                _loc_1 = callbackMap[_loc_2];
                ExternalInterface.addCallback(_loc_1.funName, _loc_1.fun);
                _loc_2++;
            }
            callbackMap = [];
            return;
        }// end function

        private static function removeTimer() : void
        {
            callMap = null;
            callbackMap = null;
            avaible = -2;
            timer.stop();
            timer.removeEventListener(TimerEvent.TIMER, tickHlr);
            timer = null;
            return;
        }// end function

        public static function addCallback(param1:String, param2:Function) : void
        {
            if (avaible == 1)
            {
                ExternalInterface.addCallback(param1, param2);
            }
            else if (avaible == 0)
            {
                callbackMap.push({funName:param1, fun:param2});
            }
            else if (avaible == -1)
            {
                callbackMap.push({funName:param1, fun:param2});
                tryCall();
            }
            return;
        }// end function

        public static function killCall(param1:Object, param2:String = null, param3:Array = null) : void
        {
            var _loc_4:Object = null;
            var _loc_7:int = 0;
            var _loc_5:Boolean = false;
            var _loc_6:* = callMap.length - 1;
            while (_loc_6 >= 0)
            {
                
                _loc_4 = callMap[_loc_6];
                _loc_5 = param2 == null ? (true) : (_loc_4.funName == param2);
                if (param2 == null)
                {
                    _loc_5 = true;
                }
                else if (_loc_4.funName == param2)
                {
                    if (param3 == null || param3.length == 0)
                    {
                        _loc_5 = true;
                    }
                    else
                    {
                        _loc_7 = 0;
                        while (_loc_7 < param3.length)
                        {
                            
                            if (param3[_loc_7] == _loc_4.params[_loc_7])
                            {
                                ;
                            }
                            _loc_7++;
                        }
                        if (_loc_7 == param3.length)
                        {
                            _loc_5 = true;
                        }
                    }
                }
                if (_loc_4.thisObj === param1 && _loc_5)
                {
                    callMap.splice(_loc_6, 1);
                }
                _loc_6 = _loc_6 - 1;
            }
            return;
        }// end function

        private static function dealCall() : void
        {
            var obj:Object;
            var callbackFun:Function;
            var callArr:Array;
            var judgeFun:Function;
            var result:*;
            var thisObj:Object;
            var yes:Boolean;
            var i:* = (callMap.length - 1);
            while (i >= 0)
            {
                
                yes;
                obj = callMap[i];
                callbackFun = obj.callbackFun;
                judgeFun = obj.judgeFun;
                thisObj = obj.thisObj;
                callArr;
                if (obj.params)
                {
                    callArr = callArr.concat(obj.params);
                }
                try
                {
                    result = JS_CALL.apply(ExternalInterface, callArr);
                    if (judgeFun != null)
                    {
                        if (result != null)
                        {
                            yes = judgeFun.apply(thisObj, [result]);
                        }
                        else
                        {
                            yes;
                        }
                    }
                    else
                    {
                        yes;
                    }
                    if (yes && callbackFun != null)
                    {
                        callbackFun.apply(thisObj, [result]);
                    }
                }
                catch (e:Error)
                {
                    TudouLogger.warn(JSCall, e.message, e.getStackTrace());
                }
                finally
                {
                    TudouLogger.debug(JSCall, obj.funName, "result：", result, "Yes:", yes, "tcount:", obj.callCount);
                    var _loc_4:* = obj;
                    _loc_4.callCount = obj.callCount - 1;
                    if (yes || obj.callCount-- <= 0)
                    {
                        if (obj == callMap[i])
                        {
                            callMap.splice(i, 1);
                        }
                    }
                }
                i = (i - 1);
            }
            if (callMap.length == 0)
            {
                timer.stop();
            }
            else
            {
                timer.reset();
                timer.start();
            }
            return;
        }// end function

        public static function justCall(param1:String, param2:Array = null)
        {
            var result:*;
            var funName:* = param1;
            var params:* = param2;
            var parArr:Array;
            if (params != null)
            {
                parArr = parArr.concat(params);
            }
            try
            {
                result = JS_CALL.apply(ExternalInterface, parArr);
            }
            catch (e:Error)
            {
                TudouLogger.warn(JSCall, e.message, e.getStackTrace());
            }
            finally
            {
                var _loc_6:* = result;
                ;
                
                
                return _loc_6;
            }
        }// end function

        public static function call(param1:Object, param2:String, param3:Function, param4:Array = null, param5:Function = null, param6:uint = 200) : void
        {
            if (avaible == -2)
            {
                return;
            }
            var _loc_7:Object = {thisObj:param1, funName:param2, callbackFun:param3, params:param4, judgeFun:param5, callCount:param6};
            if (param6 > MAX_COUNT)
            {
                MAX_COUNT = param6;
            }
            callMap.push(_loc_7);
            if (avaible == -1)
            {
                tryCall();
            }
            else if (avaible == 1)
            {
                tryCall();
            }
            else if (avaible == 0)
            {
            }
            return;
        }// end function

        private static function tickHlr(event:TimerEvent) : void
        {
            if (errorCount > MAX_COUNT)
            {
                removeTimer();
            }
            else
            {
                tryCall();
            }
            return;
        }// end function

        private static function tryCall() : void
        {
            try
            {
                dealCall();
                dealCallback();
                avaible = 1;
            }
            catch (e:Error)
            {
                var _loc_4:* = errorCount + 1;
                errorCount = _loc_4;
                timer.start();
                avaible = 0;
                TudouLogger.warn(JSCall, e.message, e.getStackTrace());
            }
            return;
        }// end function

        private static function newTimer() : void
        {
            if (timer == null)
            {
                timer = new Timer(100);
                timer.addEventListener(TimerEvent.TIMER, tickHlr);
            }
            return;
        }// end function

        newTimer();
    }
}
